package com.share.ai.langchain4j.web;

import com.share.ai.langchain4j.config.Bot;
import com.share.ai.langchain4j.config.ChatAssistant;
import dev.langchain4j.community.model.dashscope.QwenChatModel;
import dev.langchain4j.community.model.dashscope.QwenStreamingChatModel;
import dev.langchain4j.model.ollama.OllamaChatModel;
import dev.langchain4j.model.ollama.OllamaStreamingChatModel;
import dev.langchain4j.service.TokenStream;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;

@Slf4j
@RestController
public class QianWenController {
    private static final String DEFAULT_PROMPT = "你是一个博学的智能聊天助手，请根据用户提问回答！";

    //qwen对话模型
    @Autowired
    private QwenChatModel qwenChatModel;

    //qwen流式-对话模型
    @Autowired
    private QwenStreamingChatModel qwenStreamingChatModel;

    //ollama对话模型
    @Autowired
    private OllamaChatModel ollamaChatModel;

    //ollama流式-对话模型
    @Autowired
    private OllamaStreamingChatModel ollamaStreamingChatModel;

    //指定注入Ollama
    @Qualifier("ollamaChatAssistant")
    private ChatAssistant ollamaChat;

    // 指定注入千问
    @Qualifier("qwenChatAssistant")
    private ChatAssistant qwenChat;

    @Autowired
    private Bot bot;

    /**
     * 简单对话,一问一答,一次性返回所有内容
     *
     * @param userId    用户id
     * @param sessionId 对话框id
     * @param prompt    用户的问题
     * @return
     */
    @GetMapping("/chat")
    public String chat(@RequestParam(defaultValue = "default") String userId,
                       @RequestParam(defaultValue = "admin") String sessionId,
                       @RequestParam(value = "prompt", defaultValue = "你好，很高兴认识你，能简单介绍一下自己吗？") String prompt) {
        String result = null;
        String memoryId = userId + "_" + sessionId; //由用户id和会话id组成

        //不带记忆的对话
        //result = qwenChatModel.chat(query);

        //带记忆的对话
        result = qwenChat.chat(memoryId, prompt);

        return result;
    }

    /**
     * 流式对话,后端慢慢吐字 每秒5个字就是  5token/s
     * 要用到 webflux  sse
     * produces = "text/stream;chartset=UTF-8"  是设置响应流格式
     *
     * @param userId    用户id
     * @param sessionId 对话框id
     * @param prompt    用户的问题
     * @return
     */
    @GetMapping(value = "/streamChat", produces = "text/stream;chartset=UTF-8")
    public Flux<String> streamChat(@RequestParam(defaultValue = "default") String userId,
                                   @RequestParam(defaultValue = "admin") String sessionId,
                                   @RequestParam(value = "prompt", defaultValue = "你好，很高兴认识你，能简单介绍一下自己吗？") String prompt) {
        Flux<String> flux = null;
        String memoryId = userId + "_" + sessionId; //由用户id和会话id组成

        //常规的流式对话
//        flux = Flux.<String>create(fluxSink -> qwenStreamingChatModel.chat(query, new StreamingChatResponseHandler() {
//
//            @Override
//            public void onPartialResponse(String s) {
//                //s 是吐出的响应内容
//                fluxSink.next(s);
//            }
//
//            @Override
//            public void onCompleteResponse(ChatResponse chatResponse) {
//                //整个流结束的标识符---使用默认的字符
//                fluxSink.complete();
//            }
//
//            @Override
//            public void onError(Throwable throwable) {
//                //异常时
//                fluxSink.error(throwable);
//            }
//        }));

        //带记忆的流式对话
        TokenStream tokenStream = qwenChat.streamChat(memoryId, prompt);
        flux = Flux.<String>create(
                sink -> tokenStream.onPartialResponse(s -> sink.next(s))
                        .onCompleteResponse(s -> sink.complete())
                        .onError(sink::error)
                        .start()
        );
        return flux;
    }

    // 可访问mcp的机器人
    @GetMapping("/bot")
    public String bot(@RequestParam(defaultValue = "default") String userId,
                      @RequestParam(defaultValue = "admin") String sessionId,
                      @RequestParam(value = "prompt", defaultValue = "你好，很高兴认识你，能简单介绍一下自己吗？") String prompt) {
        String result = null;
        String memoryId = userId + "_" + sessionId; //由用户id和会话id组成

        //带记忆的对话
        result = bot.chat(prompt);

        return result;
    }
}
